fix(billing): hand off billing to hosted console - #408
Conversation
PeronGH
left a comment
There was a problem hiding this comment.
Two correctness issues on the typed gateway-billing path; details inline.
PeronGH
left a comment
There was a problem hiding this comment.
Correction to my earlier 503 comment (retracted inline — the mapping is contract-backed), and the real problem the Cloud contract exposes instead.
Amp-Thread-ID: https://ampcode.com/threads/T-01a00600-4239-75bb-8431-db3461ff7e4c # Conflicts: # apps/desktop/src/main/cloud-auth/client.ts # packages/client/workbench/src/settings/providers/__tests__/add-flow.test.tsx # packages/client/workbench/src/settings/providers/add-flow.tsx # packages/client/workbench/src/settings/providers/catalog.ts # packages/client/workbench/src/settings/providers/providers-settings.tsx # packages/host/agent-adapter/src/native/claude-code.ts # packages/presentation/i18n/src/locales/en.ts # packages/presentation/i18n/src/locales/zh-cn.ts # packages/presentation/ui/src/shell/conversation-surface.tsx # packages/presentation/ui/src/shell/providers/account-detail.tsx # packages/presentation/ui/src/shell/providers/account-master-list.tsx
PeronGH
left a comment
There was a problem hiding this comment.
Approving the change itself — but do not merge until the Cloud side is merged and deployed.
The gate is the deploy, not the merge. https://console.linkcode.ai/billing does not exist in production today: it and /zzz-does-not-exist both return 200 with the identical [organizationSlug] catch-all entry (<title>LinkCode</title>), i.e. prod treats billing as an org slug. The hosted route only exists on feat/code-567-hosted-billing-sdk, and linkcodehq has no deploy workflow — the console ships via a manual pnpm --filter @linkcodehq/console deploy. So merging arcboxlabs/linkcodehq#39 alone still leaves openHostedBilling() opening a dead end, and desktop cuts releases off master.
Order:
- Land arcboxlabs/linkcodehq#39 — its only conflict is
pnpm-lock.yaml(checked withgit merge-tree), so resolving it cannot changepackages/cloud/srcor the route, and the pin below stays valid. - Deploy the console, then verify
https://console.linkcode.ai/billing?returnTarget=linkcode://billing/returnrenders the Billing entry and preserves the target through sign-in + organization resolution. - Merge this PR.
What is not blocking:
- The npm publish.
packages/vendor/linkcode-cloud-0.1.0.tgzis sha256576bf95543503615204163609c49fe66ad38a3081babf5b93369a94842acdb7bas documented, and itsdist/index.jsis faithful topackages/cloud/src/index.tsat5438df8c. Thecloud-v0.1.0tag and npm bootstrap are a follow-up. - Everything outside the hosted handoff. The Gateway provider, the typed 402/503 path, and API-key creation depend only on Cloud work already merged and live:
gateway.linkcode.ai/v1/models→ 401,api.linkcode.ai/auth/get-session→ 200,/auth/api-key/create→ 400.
Both of my earlier findings are addressed — fix(gateway): preserve translated billing errors for the dead typed-error path on claude-code, and billingUnavailableHint no longer promises the request never reached the model.
Please open a follow-up issue for the vendored tarball: once @linkcode/[email protected] is on npm, swap the file: dependency for the registry package and delete the blob (@linkcode/[email protected] is the precedent). That swap will need a minimumReleaseAgeExclude entry for the fresh publish.
Summary
@linkcode/cloudSDK.openHostedBilling(): main registers the currentlinkcode:///linkcode-dev://scheme, buildshttps://console.linkcode.ai/billing?returnTarget=..., and opens it in the system browser.BillingSettingsPanel({ onOpenBilling }); LinkCode does not request, store, render, or infer billing/checkout/payment state.Linear: CODE-567
Cloud counterpart: arcboxlabs/linkcodehq#39 at
5438df8c8083f349dc3b8ed3eccdd61ca9d86358Contracts
createHostedBillingUrl(options?: { returnTarget?: string }): string;HostedBillingUrlOptionsis exported.https://console.linkcode.ai/billing[?returnTarget=<encoded>].${scheme}://billing/return, where scheme islinkcodein packaged builds andlinkcode-devin development.order=<id>and, on cancellation,canceled=true. Desktop deliberately does not parse either parameter and does not process checkout; the existing generic deep-link path only activates/focuses the app.@linkcode/[email protected], this repository consumes the official package tarball built from the Cloud commit above, pinned at SHA-256576bf95543503615204163609c49fe66ad38a3081babf5b93369a94842acdb7b.Verification
NODE_OPTIONS=--max-old-space-size=6144 pnpm check:ci— passed: format, repo-wide ESLint (0 errors; 377 existing warnings), and typecheck.pnpm test— passed: 307 files / 2443 tests; 1 existing skipped file/test.pnpm -F @linkcode/desktop run build— passed.pnpm -F @linkcode/webview run build— passed.pnpm -F @linkcode/webview e2e:browser— passed production billing-route smoke plus bundled mock router/wire/reload smoke.checkout-sessions, billing summary/orders, or portal-session endpoints.linkcode-dev://billing/return?order=...- Commit hookscanceled=true, observed one restored/focused window, and observed no local checkout-result UI.Checklist
pnpm check:ciandpnpm testboth pass